#include "config.hpp"
#include "util.hpp"
#include "data.hpp"
#include "hot.hpp"
#include "service.hpp"
#include <thread>

cloud::DataManager *data = new cloud::DataManager; // 定义这个全局变量，确保服务器运行期间用的是同一个数据管理类对象
// 该变量已在各个头文件中声明

void FileUtilTest(const std::string &filename)
{
	// 测试获取文件属性接口
	// cloud::FileUtil fu(filename);
	// std::cout << fu.FileSize() << std::endl;
	// std::cout << fu.LastMTime() << std::endl;
	// std::cout << fu.LastATime() << std::endl;
	// std::cout << fu.FileName() << std::endl;

	// 测试读写文件内容的接口
	//  cloud::FileUtil fu(filename);
	//  std::string body;
	//  fu.GetContent(body);
	//  cloud::FileUtil nfu("./hello.txt");
	//  nfu.SetContent(body);

	// 测试压缩和解压缩文件的接口
	//  std::string packname = filename + ".lz";
	//  cloud::FileUtil fu(filename);
	//  fu.Compress(packname);
	//  cloud::FileUtil pfu(packname);
	//  pfu.UnCompress("./jieya.txt");

	// 测试文件目录相关接口
	// cloud::FileUtil fu(filename);
	// fu.CreateDirectory();
	// std::vector<std::string> arry;
	// fu.ScanDirectory(arry);
	// for (auto &a : arry)
	// {
	// 	std::cout << a << std::endl;
	// }
}

void JsonUtilTest()
{
	const char *name = "小明";
	int age = 19;
	float score[] = {85, 88.5, 99};
	Json::Value root;
	root["姓名"] = name;
	root["年龄"] = age;
	root["成绩"].append(score[0]);
	root["成绩"].append(score[1]);
	root["成绩"].append(score[2]);
	// 序列化
	std::string json_str;
	cloud::JsonUtil::Serialize(root, json_str);
	std::cout << json_str << std::endl
			  << std::endl;

	// 反序列化
	Json::Value val;
	cloud::JsonUtil::UnSerialize(json_str, val);
	std::cout << val["姓名"].asString() << std::endl;
	std::cout << val["年龄"].asInt() << std::endl;
	for (int i = 0; i < val["成绩"].size(); i++)
	{
		std::cout << val["成绩"][i].asFloat() << std::endl;
	}
}

void ConfigTest()
{
	// 这里测试一开始遇到了一个bug，因为Config类里面两个静态成员变量在类外初始化的时候没有指定类域
	cloud::Config *config = cloud::Config::GetInstance();
	std::cout << config->GetHotTime() << std::endl;
	std::cout << config->GetServerPort() << std::endl;
	std::cout << config->GetServerIp() << std::endl;
	std::cout << config->GetDownloadPrefix() << std::endl;
	std::cout << config->GetPackFileSuffix() << std::endl;
	std::cout << config->GetPackDir() << std::endl;
	std::cout << config->GetBackDir() << std::endl;
	std::cout << config->GetBackupFile() << std::endl;
}

//测试数据管理模块
void DataTest(const std::string &filename)
{
	cloud::DataManager data;
	std::vector<cloud::BackupInfo> arry;
	data.GetAll(arry);
	for (auto &a : arry)
	{
		std::cout << a._pack_flag << std::endl;
		std::cout << a._file_size << std::endl;
		std::cout << a._modify_time << std::endl;
		std::cout << a._access_time << std::endl;
		std::cout << a._real_path << std::endl;
		std::cout << a._pack_path << std::endl;
		std::cout << a._url_path << std::endl;
	}

	// cloud::BackupInfo info;
	// info.InitBackupInfo(filename);
	// cloud::DataManager data;
	// std::cout << "-----------insert and GetOneByURL--------\n";
	// data.Insert(info);
	// cloud::BackupInfo tmp;
	// data.GetOneByURL("/download/bundle.h", tmp);
	// std::cout << tmp._pack_flag << std::endl;
	// std::cout << tmp._file_size << std::endl;
	// std::cout << tmp._modify_time << std::endl;
	// std::cout << tmp._access_time << std::endl;
	// std::cout << tmp._real_path << std::endl;
	// std::cout << tmp._pack_path << std::endl;
	// std::cout << tmp._url_path << std::endl;

	// std::cout << "-----------update and getall--------\n";
	// info._pack_flag = true;
	// data.Update(info);
	// std::vector<cloud::BackupInfo> arry;
	// data.GetAll(arry);
	// for (auto &a : arry)
	// {
	// 	std::cout << a._pack_flag << std::endl;
	// 	std::cout << a._file_size << std::endl;
	// 	std::cout << a._modify_time << std::endl;
	// 	std::cout << a._access_time << std::endl;
	// 	std::cout << a._real_path << std::endl;
	// 	std::cout << a._pack_path << std::endl;
	// 	std::cout << a._url_path << std::endl;
	// }

	// std::cout << "-----------GetOneByRealPath--------\n";
	// data.GetOneByRealPath(filename, tmp);
	// std::cout << tmp._pack_flag << std::endl;
	// std::cout << tmp._file_size << std::endl;
	// std::cout << tmp._modify_time << std::endl;
	// std::cout << tmp._access_time << std::endl;
	// std::cout << tmp._real_path << std::endl;
	// std::cout << tmp._pack_path << std::endl;
	// std::cout << tmp._url_path << std::endl;
}

//测试热点管理
void HotTest()
{
	cloud::HotManager hot;
	hot.RunModule();
}

void ServiceTest()
{
	cloud::Service srv;
	srv.RunModule();
	//这里测试时一开始不行，因为云服务器bind时不能指明IP，这里把配置文件中的IP改成0.0.0.0，让服务器自己指定可用IP
}

int main(int argc, char *argv[])
{
	// cout << sizeof(long) << endl; // 8字节

	// FileUtilTest(argv[1]);
	//  JsonUtilTest();
	//  ConfigTest();
	// DataTest(argv[1]);
	//HotTest();
	//ServiceTest();

	//未来服务器运行起来，业务处理和热点管理肯定要同时进行，所以我们要使用多线程来分别执行不同的功能模块
	std::thread HotManager(HotTest);//传入线程入口函数，无参
	std::thread Service(ServiceTest);

	//等待线程
	HotManager.join();
	Service.join();
	
	return 0;
}